package com.codepilot.server.service.impl;

import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.codepilot.server.model.dto.UserDTO;
import com.codepilot.server.model.entity.User;
import com.codepilot.server.model.exception.enums.GlobalErrorCodeConstants;
import com.codepilot.server.mapper.UserMapper;
import com.codepilot.server.service.UserService;
import com.codepilot.server.utils.ImgUtil;
import com.codepilot.server.utils.RedisCache;
import cn.hutool.core.util.RandomUtil;
import com.codepilot.server.model.vo.CommonResult;
import com.codepilot.server.model.vo.DisplayUserVO;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ImgUtil imgUtil;

    @Autowired
    private JavaMailSender javaMailSender;

    @Value("${spring.mail.username}")
    private String from;

    @Override
    public CommonResult<?> getInfo() {
        Authentication authorization = SecurityContextHolder.getContext().getAuthentication();
        UserDTO loginUser = (UserDTO) authorization.getPrincipal();

        // if (loginUser == null) {
        // return ResponseEntity.badRequest().body("用户不存在");
        // }

        DisplayUserVO displayUserVO = new DisplayUserVO(loginUser.getUser());
        return CommonResult.success(displayUserVO);
    }

    @Override
    public CommonResult<?> modify(DisplayUserVO displayUserVO) {
        Authentication authorization = SecurityContextHolder.getContext().getAuthentication();
        UserDTO loginUser = (UserDTO) authorization.getPrincipal();

        User user = loginUser.getUser();
        user.update(displayUserVO);

        try {
            userMapper.modify(user);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        return CommonResult.success("修改成功");
    }

    @Override
    public CommonResult<?> modifyAvatar(MultipartFile file) {
        Authentication authorization = SecurityContextHolder.getContext().getAuthentication();
        UserDTO loginUser = (UserDTO) authorization.getPrincipal();

        User user = loginUser.getUser();

        String filePath = null;
        try {
            filePath = imgUtil.uploadFile(file, user.getUsername());
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
        }

        user.setAvatar(filePath);
        try {
            userMapper.modify(user);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        return CommonResult.success("修改成功");
    }

    @Override
    public CommonResult<?> forget(String email) {
        User user = userMapper.findByEmail(email);

        if (user == null) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }

        SimpleMailMessage message = new SimpleMailMessage();
        String captcha = RandomUtil.randomNumbers(6);
        message.setText("验证码：" + captcha);
        message.setSubject("Codepilot验证码");
        message.setFrom(from);
        message.setTo(email);

        try {
            javaMailSender.send(message);
            redisCache.setCacheObject("captcha:" + user.getUsername(), captcha, 300L,
                    TimeUnit.SECONDS);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        return CommonResult.success(null);
    }

    @Override
    public CommonResult<?> checkCaptcha(String email, String captcha) {
        User user = userMapper.findByEmail(email);

        if (user == null) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }

        String realCaptcha = null;
        try {
            realCaptcha = redisCache.getCacheObject("captcha:" + user.getUsername());
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        if (realCaptcha == null || !realCaptcha.equals(captcha)) {
            return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
        } else {
            redisCache.deleteObject("captcha:" + user.getUsername());
            redisCache.setCacheObject("reset:" + user.getUsername(), true, 300, TimeUnit.SECONDS);
            return CommonResult.success(null);
        }
    }

    @Override
    public CommonResult<?> passwd(String email, String oldPassword, String password) {
        User user;

        Authentication authorization = SecurityContextHolder.getContext().getAuthentication();
        // UserDTO loginUser = (UserDTO) authorization.getPrincipal();

        if (authorization.getPrincipal().equals("anonymousUser")) {
            user = userMapper.findByEmail(email);
            if (user == null || redisCache.getCacheObject("reset:" + user.getUsername()) == null) {
                return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
            } else {
                redisCache.deleteObject("reset:" + user.getUsername());
            }
        } else {
            UserDTO loginUser = (UserDTO) authorization.getPrincipal();
            user = loginUser.getUser();
            if (!oldPassword.equals(user.getPassword())) {
                return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
            }
        }

        user.setPassword(passwordEncoder.encode(password));

        try {
            userMapper.passwd(user);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        // 修改密码后，需要清理redis缓存，退出登录
        redisCache.deleteObject("login:" + user.getUsername());

        return CommonResult.success("修改成功");
    }

    @Override
    public CommonResult<?> logout() {
        Authentication authorization = SecurityContextHolder.getContext().getAuthentication();
        UserDTO loginUser = (UserDTO) authorization.getPrincipal();

        redisCache.deleteObject("login:" + loginUser.getUsername());
        return CommonResult.success("退出成功");
    }

    @Override
    public CommonResult<?> unregister() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDTO loginUser = (UserDTO) authentication.getPrincipal();

        User user = loginUser.getUser();

        try {
            userMapper.unregister(user);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        return CommonResult.success("注销成功");
    }

    public Integer getUserId(String username) {
        User user = userMapper.findByUsername(username);
        return user.getId();
    }
}
